package com.ihr360.payroll.service.salaryfield.impl;

import com.google.common.collect.Lists;
import com.ihr360.authority.sharing.annonation.AccessControl;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.vo.PageData;
import com.ihr360.payroll.config.system.SystemSalaryFieldEntity;
import com.ihr360.payroll.dao.SalaryFieldTypeRepository;
import com.ihr360.payroll.dao.SystemSalaryFieldRepository;
import com.ihr360.payroll.model.dto.salary.basecode.SalaryFieldType;
import com.ihr360.payroll.model.dto.salary.meta.system.SystemSalaryField;
import com.ihr360.payroll.service.payroll.convertor.SystemSalaryFieldConvertor;
import com.ihr360.payroll.service.salaryfield.SystemSalaryFieldService;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import com.ihr360.validation.ValidationUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author richey
 */
@Service
@AccessControl(disableAll = true)
public class SystemSalaryFieldServiceImpl extends AbstractSimpleRestServiceImpl<SystemSalaryField, Long> implements SystemSalaryFieldService {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private SystemSalaryFieldRepository systemSalaryFieldReposity;
    @Autowired
    private SalaryFieldTypeRepository salaryFieldTypeRepository;

    @Autowired
    SystemSalaryFieldConvertor systemSalaryFieldConvertor;

    @Override
    public SimpleRestReposity<SystemSalaryField, Long> getSimpleRestReposity() {
        return systemSalaryFieldReposity;
    }

    @Override
    public PageData<SystemSalaryFieldEntity> pageListByCategory(Long categoryId, Pageable pageable) {
        Page<SystemSalaryField> page = systemSalaryFieldReposity.findByCategory(categoryId, pageable);
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new PageData<>(page.getTotalPages(), page.getTotalElements(), Lists.newArrayList());
        }
        List<SystemSalaryFieldEntity> systemSalaryFieldEntities = getSystemSalaryFieldEntities(page.getContent());
        return new PageData<>(page.getTotalPages(), page.getTotalElements(), systemSalaryFieldEntities);
    }


    @Override
    public List<SystemSalaryFieldEntity> listExcludeId(Long excludeId) {
        List<SystemSalaryField> systemSalaryFields = Lists.newArrayList();
        if (excludeId != null) {
            systemSalaryFieldReposity.findByIdNot(excludeId);
        } else {
            systemSalaryFields = (List<SystemSalaryField>) systemSalaryFieldReposity.findAll();
        }
        return getSystemSalaryFieldEntities(systemSalaryFields);
    }

    @Override
    public SystemSalaryFieldEntity saveOrUpdate(SystemSalaryFieldEntity entity) {
        SystemSalaryField systemSalaryField = systemSalaryFieldConvertor.convertEntityToDto(entity);
        String code = systemSalaryField.getCode();
        ValidationUtils.rejectIfEmptyOrWhitespace(code, null, "薪资项目编号不能为空！");
        if (Character.isDigit(code.trim().charAt(0))) {
            throw new Ihr360Exception(null, "薪资项目编号必须以数字开头");
        }

        SalaryFieldType salaryFieldType = salaryFieldTypeRepository.findOne(entity.getType().getId());
        systemSalaryField.setType(salaryFieldType);
        try {
            systemSalaryField = systemSalaryFieldReposity.save(systemSalaryField);
        } catch (org.springframework.dao.DataIntegrityViolationException e) {
            throw new Ihr360Exception(null, "该记录已存在或存在相同约束的记录");
        }
        return systemSalaryFieldConvertor.convertDtoToEntity(systemSalaryField);
    }

    @Override
    public List<SystemSalaryFieldEntity> listByCategory(Long categoryId) {
        ValidationUtils.rejectIfEmpty(categoryId, null, "薪资项目大类不能为空！");
        List<SystemSalaryField> systemSalaryFields = systemSalaryFieldReposity.findByCategory(categoryId);
        return getSystemSalaryFieldEntities(systemSalaryFields);
    }

    @Override
    public List<SystemSalaryFieldEntity> listBySalaryFieldType(Long salaryFieldTypeId,Boolean showInStaffSalary) {
        ValidationUtils.rejectIfEmpty(salaryFieldTypeId, null, "薪酬字段类型不能为空！");
        List<SystemSalaryField> systemSalaryFields = Lists.newArrayList();
        if (showInStaffSalary == null) {
            systemSalaryFields = systemSalaryFieldReposity.findByType(salaryFieldTypeId);
        }else{
            if (showInStaffSalary) {
                systemSalaryFields = systemSalaryFieldReposity.findByTypeAndCanShowInStaffSalary(salaryFieldTypeId);
            }else{
                systemSalaryFields = systemSalaryFieldReposity.findByTypeAndCanNotShowInStaffSalary(salaryFieldTypeId);
            }

        }
        return getSystemSalaryFieldEntities(systemSalaryFields);
    }

    @Override
    public SystemSalaryFieldEntity findByCode(String fieldCode) {
        ValidationUtils.rejectIfEmpty(fieldCode, null, "薪资字段编码不能为空！");
        SystemSalaryField systemSalaryField = systemSalaryFieldReposity.findByCode(fieldCode);
        if (systemSalaryField == null) {
            return null;
        }
        return systemSalaryFieldConvertor.convertDtoToEntity(systemSalaryField);
    }

    @Override
    public SystemSalaryFieldEntity findById(Long id) {
        ValidationUtils.rejectIfEmpty(id, null, "薪资字段id不能为空！");
        SystemSalaryField systemSalaryField = systemSalaryFieldReposity.findOne(id);
        if (systemSalaryField == null) {
            return null;
        }
        return systemSalaryFieldConvertor.convertDtoToEntity(systemSalaryField);
    }

    @Override
    public void deleteById(Long id) {
        systemSalaryFieldReposity.delete(id);
    }

    @Override
    public List<SystemSalaryFieldEntity> filterCountField(boolean countField) {
        List<SystemSalaryField> systemSalaryFields = systemSalaryFieldReposity.findByCountFieldIs(countField);
        if (CollectionUtils.isEmpty(systemSalaryFields)) {
            return Lists.newArrayList();
        }
        return systemSalaryFieldConvertor.convertDtosToEntities(systemSalaryFields);
    }

    @Override
    public List<SystemSalaryFieldEntity> getAllStatisticsSystemSalaryField() {
        List<SystemSalaryField> systemSalaryFields = (List<SystemSalaryField>) systemSalaryFieldReposity.findAll();

        if (CollectionUtils.isEmpty(systemSalaryFields)) {
            return Lists.newArrayList();
        }
        return systemSalaryFieldConvertor.convertDtosToEntities(systemSalaryFields);
    }

    @Override
    public List<SystemSalaryFieldEntity> listCanShowInStaffSalary() {
        List<SystemSalaryField> systemSalaryFields = systemSalaryFieldReposity.findCanShowInStaffSalary();
        return getSystemSalaryFieldEntities(systemSalaryFields);
    }

    private List<SystemSalaryFieldEntity> getSystemSalaryFieldEntities(List<SystemSalaryField> systemSalaryFields) {
        List<SystemSalaryFieldEntity> systemSalaryFieldEntities = Lists.newArrayListWithCapacity(systemSalaryFields.size());
        systemSalaryFields.forEach(salaryField -> {
            SystemSalaryFieldEntity systemSalaryFieldEntity = systemSalaryFieldConvertor.convertDtoToEntity(salaryField);
            systemSalaryFieldEntities.add(systemSalaryFieldEntity);
        });
        return systemSalaryFieldEntities;
    }

}
